--
-- @Author:			
-- @DateTime:	2019-04-22 16:05:48
-- @Description: 客户端socket连接、断开、错误状态消息的处理


local skynet = require "skynet"
local log = require "Logger"


local service_index = 1
local MessageSession = class("MessageSession")



-- 初始化
function MessageSession:ctor(...)
	self.session_list = {} 
	self.session_services = {} --处理socket的服务列表
	self.session_user_id_list = {} --[user_id]=session

	--socket状态消息
	self.socket_handler = {}
	self.socket_handler.open = handler(self,self.openSocket)
	self.socket_handler.close = handler(self,self.closeSocket)
	self.socket_handler.error = handler(self,self.errorSocket)
	self.socket_handler.warning = handler(self,self.warningSocket)
	self.socket_handler.data = handler(self,self.dataSocket)	
end

function MessageSession:addSessionService(session_service)
	table.insert(self.session_services, session_service)
end

function MessageSession:getSessionServices()
	return self.session_services
end

function MessageSession:getSession(session_id)
	return self.session_list[session_id]
end

function MessageSession:getSessionByUserId(user_id)
	return self.session_user_id_list[user_id]
end

function MessageSession:removeSession(session_id)
	if self.session_list[session_id] then
		--断开连接
		local session = self.session_list[session_id]
		if session and session.gate then 
			skynet.send(session.gate, "lua", "kick", session.fd)		
		end
		self.session_list[session_id] = nil
		return true
	end

	return false
end

--user_id 绑定 session
function MessageSession:bindSession(user_id,session_id)
	if not self.session_list[session_id] then
		print("#########绑定user_id session 失败",user_id,session_id)
		return false
	end	
	self.session_user_id_list[user_id] = self.session_list[session_id]
	return true
end

function MessageSession:unbindSession(user_id)
	if not self.session_user_id_list[user_id] then
		return false
	end
	self.session_user_id_list[user_id] = nil
end

--取user 所在service
function MessageSession:getServiceByUserId(user_id)
	local session = self.session_user_id_list[user_id] 
	if session and next(session) then
		return session.service
	end
	log.debug("______用户对应的gate_service不存在",user_id,self.session_user_id_list,self.session_list)
	return false
end

-------------------------------------------------------------------
--- 用户连接
--- @param fd @class number 连接标识符
--- @param addr @class string 连接地址
--- @param contype@class string 连接类型
function MessageSession:openSocket(gate, fd, addr, contype)
	log.debug("___new client fd:" ..fd .." from :".. addr)

	local gate_service = self.session_services[service_index]
	service_index = service_index + 1
	if service_index > #self.session_services then
		service_index = 1
	end

	self.session_list[fd] = {
		fd = fd, 
		gate = gate, --gate.lua
		service = gate_service, --gate_service
		addr = addr, 
		contype = contype --连接类型 socket websocket
	}

	local strTtems = splitString(addr, ':')
	addr = strTtems[1]
	skynet.call(gate_service, "lua", "connect", {
		service     = gate,
		fd      	= fd,
		addr 		= addr,
		contype     = contype,
	})

end

--socket关闭
function MessageSession:closeSocket(watchdog, fd)
	log.debug("####client socket close", fd)
	if not self.session_list[fd] then 
		--客户端连接被清除
		print("__客户端连接被清除__",fd)
		return 
	end
	local gate_service = self.session_list[fd].service
	if not gate_service then 
		return 
	end
	skynet.call(gate_service, "lua", "disconnect", fd)
end

--socket错误
function MessageSession:errorSocket(watchdog, fd, msg)
	-- print("####client socket error", fd, msg)
	log.debug("####client socket error", fd, msg)
	if not self.session_list[fd] then 
		--客户端连接被清除
		print("__客户端连接被清除__",fd)
		return 
	end
	local gate_service = self.session_list[fd].service
	skynet.call(gate_service, "lua", "disconnect", fd, msg)
end

function MessageSession:warningSocket(watchdog, fd, size)
	-- log.info("client socket warning", fd, size)
end

function MessageSession:dataSocket(watchdog, fd, msg)
	log.debug("####client socket data", fd, msg)
	local gate_service = self.session_list[fd].service
	skynet.call(gate_service, "lua", "recv", fd, msg)
end

--socket相关状态消息
function MessageSession:dispatch(source, cmd, ... )
	-- print("######",source, cmd, ... )
	local func = self.socket_handler[cmd]	
	if func then
		func(source, ...)
	end
end

return MessageSession